package com.edrive.surveyor;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Locale;

import com.edrive.surveyor.comon.AppConstant;
import com.edrive.surveyor.comon.HttpASync;
import com.edrive.surveyor.comon.HttpASync.OnRequest;
import com.edrive.surveyor.R;

import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.content.Context;

import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.Toast;

public class Surveyor extends Activity implements OnClickListener, OnRequest {

	private static final long MINIMUM_DISTANCE_CHANGE_FOR_UPDATES = 100; // in
																		// Meters
	private static final long MINIMUM_TIME_BETWEEN_UPDATES = 10000;
	protected LocationManager locationManager;
	static double n = 0;
	Long s1, r1;
	double plat, plon, clat, clon, dis;
	private Location location;
	Thread t1;
	boolean bool = true;
	private Button startStop;

	private Spinner alertSpinner;
	private String[] alerts = { "Traffic Jam", "Slow Moving Traffic", "Rain",
			"Snowfall", "Intercepter", "License Checking", "Helmet Checking",
			"Accident" };
	private long startTime;
	private long endTime;
	private ImageView alertButton;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_surveyor);
		startStop = (Button) findViewById(R.id.button1);
		alertSpinner = (Spinner) findViewById(R.id.spinner1);
		alertButton = (ImageView) findViewById(R.id.imageView2);
		startStop.setTag("stop");
		locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
				MINIMUM_TIME_BETWEEN_UPDATES,
				MINIMUM_DISTANCE_CHANGE_FOR_UPDATES, new MyLocationListener());
		startStop.setOnClickListener(this);
		alertButton.setOnClickListener(this);
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		showCurrentLocation(true);

		ArrayAdapter adapter = new ArrayAdapter(this,
				android.R.layout.simple_spinner_item, alerts);
		alertSpinner.setMinimumHeight(125);
		alertSpinner.setAdapter(adapter);
	}

	protected void showCurrentLocation(boolean setStart) {

		location = locationManager
				.getLastKnownLocation(LocationManager.GPS_PROVIDER);

		if (location != null) {
			String message = String
					.format("Current Location from GPS \n Longitude: %1$s \n Latitude: %2$s",
							location.getLongitude(), location.getLatitude());
			// plat=location.getLatitude();
			// plon=location.getLongitude();
			Toast.makeText(Surveyor.this, message, Toast.LENGTH_SHORT).show();
			if (setStart) {
				startTime = System.currentTimeMillis();
				plat = location.getLatitude();
				plon = location.getLongitude();
			}
		} else {
			Toast.makeText(Surveyor.this, "null location", Toast.LENGTH_LONG)
					.show();

			location = locationManager
					.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

			if (location != null) {
				String message = String
						.format("Current Location from Network \n Longitude: %1$s \n Latitude: %2$s",
								location.getLongitude(), location.getLatitude());
				plat = location.getLatitude();
				plon = location.getLongitude();
				Toast.makeText(Surveyor.this, message, Toast.LENGTH_SHORT)
						.show();
				if (setStart) {
					startTime = System.currentTimeMillis();
					plat = location.getLatitude();
					plon = location.getLongitude();
				}
			} else {
				Toast.makeText(Surveyor.this, "null location",
						Toast.LENGTH_SHORT).show();
			}
		}

	}

	@Override
	public void onClick(View v) {

		switch (v.getId()) {

		case R.id.button1:
			String state = (String) startStop.getTag();
			if (state.equals("stop")) {
				startStop.setText("Stop Journey");
				startStop.setTag("start");
				// t1=new Thread();
				// t1.start();//
				handler.post(r);

			} else {
				startStop.setText("Start Journey");
				startStop.setTag("stop");
				// /counter.cancel();
				bool = false;
				handler.removeCallbacks(r);
			}

			break;
		case R.id.imageView2:
			String alertMessage = (String) alertSpinner.getSelectedItem();
			showCurrentLocation(false);
			String address = "NA";

			if (location != null) {
				address = ConvertPointToLocation();
				String decodeAddress = "";
				String decodeMessage = "";
				try {
					decodeAddress = URLEncoder.encode(address, "UTF-8");
					decodeMessage = URLEncoder.encode(alertMessage, "UTF-8");
				} catch (UnsupportedEncodingException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				String url = AppConstant.ALERT + "?lat="
						+ location.getLatitude() + "&long="
						+ location.getLongitude() + "&alert=" + decodeMessage
						+ "&time=" + System.currentTimeMillis() + "&des="
						+ decodeAddress;
				HttpASync async = new HttpASync();

				// async.setOnRequestListener(Surveyor.this);
				async.execute(url);
				Toast.makeText(Surveyor.this, "Sending Alert about " + address,
						Toast.LENGTH_LONG).show();
			}

			break;

		}
	}

	public String ConvertPointToLocation() {
		String address = "";
		Geocoder geoCoder = new Geocoder(getBaseContext(), Locale.getDefault());
		try {
			List<Address> addresses = geoCoder.getFromLocation(
					location.getLatitude(), location.getLongitude(), 1);

			if (addresses.size() > 0) {
				for (int index = 0; index < addresses.get(0)
						.getMaxAddressLineIndex(); index++)
					address += addresses.get(0).getAddressLine(index) + " ";
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

		return address;
	}

	Handler handler = new Handler();
	Runnable r = new Runnable() {

		@Override
		public void run() {
			System.out.println("run");

			showCurrentLocation(false);
			if (location != null) {
				clat = location.getLatitude();
				clon = location.getLongitude();
				//if (clat != plat || clon != plon) {
					dis = getDistance(plat, plon, clat, clon, 'K')*1000;
					
					endTime = System.currentTimeMillis();
					String url = AppConstant.DISTANCE + "?lat1=" + plat
							+ "&long1=" + plon + "&lat2=" + clat + "&long2="
							+ clon + "&starttime=" + startTime + "&endtime="
							+ endTime;// +"&distance="+dis;
					plat = clat;
					plon = clon;
					startTime = endTime;

					System.out.println("Run :: distance = " + dis);
					//if (dis >= MINIMUM_DISTANCE_CHANGE_FOR_UPDATES) {
						HttpASync async = new HttpASync();

						// async.setOnRequestListener(Surveyor.this);
						async.execute(url);
						Message msg = new Message();
						msg.obj = "Sending Location update  to server :Distance : "
								+ dis;
						toastHandler.handleMessage(msg);
					
				//}
			} else {
				Message msg = new Message();
				msg.obj = "location null";
				toastHandler.handleMessage(msg);
			}
				
				
			handler.postDelayed(r, MINIMUM_TIME_BETWEEN_UPDATES);

		}

		public double getDistance(double lat1, double lon1, double lat2,
				double lon2, char unit) {
			double theta = lon1 - lon2;
			double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2))
					+ Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2))
					* Math.cos(deg2rad(theta));
			dist = Math.acos(dist);
			dist = rad2deg(dist);
			dist = dist * 60 * 1.1515;
			if (unit == 'K') {
				dist = dist * 1.609344;
			} else if (unit == 'N') {
				dist = dist * 0.8684;
			}
			return (dist);
		}

		/* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
		/* :: This function converts decimal degrees to radians : */
		/* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
		private double deg2rad(double deg) {
			return (deg * Math.PI / 180.0);
		}

		/* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
		/* :: This function converts radians to decimal degrees : */
		/* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
		private double rad2deg(double rad) {
			return (rad * 180.0 / Math.PI);
		}

	};

	Handler toastHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			final String message = (String) msg.obj;
			runOnUiThread(new Runnable() {

				@Override
				public void run() {
					Toast.makeText(Surveyor.this, message, Toast.LENGTH_SHORT)
							.show();
				}
			});

		};
	};

	@Override
	public void onResponseReceived(String response) {
		// TODO Auto-generated method stub

	}
}
